package cn.org.cute.ebocy.util;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 *  时间和日期处理类
 * @Copyright©2011, 2011 EBO CHANGYOU Co.td. All rights reserved.
 * @Version 1.0.0
 * @since jdk1.6
 * @author xiaolei
 * @date 2011-12-13
 */
public class DateUtil {
	public static final int DAY_SECONDS = 24 * 60 * 60;

	public final static String DATE_PATTERN = "yyyy-MM-dd";

	public final static String TIME_PATTERN = "HH:mm:ss";

	public final static String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

	public final static String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss.fff";

	public final static String SHOW_DATETIME_PATTERN = "yyyy-MM-dd HH:mm";

	public static final Timestamp NOTAVAIABLE = str2Date("2037-12-31",DATE_PATTERN);

	// /////////////////////////////////////////////////////////
	// java.sql.Timestamp Functions
	// /////////////////////////////////////////////////////////
	/**
	 * 得到两个时间的差值,以秒记
	 * 
	 * 
	 * @param bigDate
	 * @param smallDate
	 * @return
	 */
	public static long secondDistance(Timestamp bigDate, Timestamp smallDate) {
		if (bigDate == null || smallDate == null)
			return 0;
		int c = bigDate.compareTo(smallDate) ;
		if(c == 0) {
			return 0L ;
		} else if( c < 0){
			Timestamp f = bigDate ;
			bigDate = smallDate ;
			smallDate = f ;
		}
		return (bigDate.getTime() - smallDate.getTime()) / 1000;
	}

	public static long secondDistance(Timestamp bigDate) {
		return secondDistance(bigDate, nowTimestamp());
	}
	
	/**
	 * 所给时间与当前时间的时间差（秒）
	 * @param bigDate yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static long secondDistance(String bigDate) {
		return secondDistance(str2Date(bigDate), nowTimestamp());
	}

	public static long minuteDistance(Timestamp bigDate, Timestamp smallDate){
		long sencodDistance = secondDistance(bigDate, nowTimestamp());
		
		return sencodDistance/60;
	}
	
	/**
	 * 是否是今天
	 * @param date1
	 * @return
	 */
	public static boolean isToday (Date date) {
		return isSameDay(date, new Date()) ;
	}
	
	/**
	 * 是否是同一天
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameDay(Date date1, Date date2) {
		if (date1 == null || date2 == null) {
			return false ;
		}
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
	}
	 
	public static boolean isSameDay(Calendar cal1, Calendar cal2) {
		if (cal1 == null || cal2 == null) {
			throw new IllegalArgumentException("The date must not be null");
		}
		return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
				cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
				cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
	}
	
	public static boolean isSameDateTime (Date date1, Date date2) {
		if(date1==null || date2 == null) return false ;
		return date1.getTime()==date2.getTime();//bigDate.getTime() - smallDate.getTime()
	}
	
	/**
	 * 判断两个时间是否在同一个小时区间内.
	 * 
	 * @param time1
	 * @param time2
	 * @param distHour
	 *            小时区间标识值，如[0-4]、[5-8]...
	 * @return
	 */
	public static boolean isInSameDist(Timestamp time1, Timestamp time2,
			int distHour) {
		if (time1 == null || time2 == null) {
			return false;
		}
		if (!isSameDay(time1, time2)) {
			return false;
		}
		int hour1 = getHours(time1);
		int hour2 = getHours(time2);

		if (Math.abs(hour1 - hour2) > distHour) {
			return false;
		}
		int distIndex1 = getDistIndex(hour1, distHour);
		int distIndex2 = getDistIndex(hour2, distHour);
		if (distIndex1 == -1 || distIndex2 == -1 || distIndex1 != distIndex2) {
			return false;
		}

		return true;
	}

	/**
	 * 根据小时区间标识值，将24小时划分区间，并判断传递参数所在区间
	 * 
	 * @param hour
	 * @param distHour
	 * @return
	 */
	public static int getDistIndex(int hour, int distHour) {
		int distSize = Calendar.HOUR_OF_DAY % distHour == 0 ? Calendar.HOUR_OF_DAY
				/ distHour
				: Calendar.HOUR_OF_DAY / distHour + 1;
		for (int i = 0; i < distSize; i++) {
			if (hour >= i * distSize && hour < (i + 1) * distSize) {
				return i + 1;
			}
		}
		return -1;
	}

	/**
	 * 获得日期小时值
	 * 
	 * @param time
	 * @return
	 */
	public static int getHours(Timestamp time) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(time);
		return cal.get(Calendar.HOUR_OF_DAY);
	}
	
	/**
	 * 获取当前时间的小时值
	 * @return
	 */
	public static int getHours () {
		return getHours(nowTimestamp()) ;
	}
	
	/**
	 * 获取今日的日期
	 * @return
	 */
	public static String today() {
		return getDatetime(new Date(), DATE_PATTERN);
	}
	
	/**
	 * 获取今日剩余的毫秒数
	 * @return
	 */
	public static long getDayLeftMillisecond () {
		int hour = getHours();
		long expiry = (hour > 12) ? (24 - hour) : (12-hour) ;
		return  expiry*3600000 ;
	}
	
	public static String getDaySection () {
		int hour = getHours();
		String section = (hour < 12) ? "am" : "pm" ;
		return today () + section ;
	}
	
	
	
	/**
	 * 以当前时间为基准, 向前(后)推移若干秒
	 * 
	 * 
	 * @param second
	 * @return
	 */
	public static Timestamp moveSecond(long second) {
		return moveSecond(nowTimestamp(), second);
	}

	/**
	 * 以给定时间为基准, 向前(后)推移若干秒
	 * 
	 * 
	 * @param baseDttm
	 * @param second
	 * @return
	 */
	public static Timestamp moveSecond(Timestamp baseDttm, long second) {
		if (baseDttm == null)
			baseDttm = nowTimestamp();
		long time = baseDttm.getTime();
		time += second * 1000;

		return new Timestamp(time);
	}

	/**
	 * Return a Timestamp for right now
	 */
	public static java.sql.Timestamp nowTimestamp() {
		return new java.sql.Timestamp(new Date().getTime());
	}

	public static java.sql.Timestamp newTimestamp(long time) {
		return new java.sql.Timestamp(time);
	}
	
	/**
	 * 计算当前时间，是否在俩时间之内
	 * @param startTime "年-月-日 时：分：秒"
	 * @param endTime
	 * @return
	 */
	public static boolean betweenDateTime(String startTime, String endTime) {
		Timestamp tsStart = str2Date(startTime, DATETIME_PATTERN);
		Timestamp tsEnd = str2Date(endTime, DATETIME_PATTERN);
		return betweenTime(tsStart,tsEnd) ;
	}
	
	/**
	 * 计算当前日期，是否在俩日期之内
	 * @param startTime "年-月-日"
	 * @param endTime
	 * @return
	 */
	public static boolean betweenDate(String startTime, String endTime) {
		return betweenDate(startTime+" 00:00:01", endTime+" 23:59:59") ;
	}
	

	/**
	 * 当前时间是否在某个时间段内
	 * @param startTime
	 *            HH:MM:SS
	 * @param endTime
	 *            HH:MM:SS
	 * @return
	 */
	public static boolean betweenTime(String startTime, String endTime) {
		String sTime = getDate(nowTimestamp()) + " " + startTime;
		String eTime = getDate(nowTimestamp()) + " " + endTime;

		Timestamp tsStart = str2Date(sTime, DATETIME_PATTERN);
		Timestamp tsEnd = str2Date(eTime, DATETIME_PATTERN);
		Timestamp now = nowTimestamp();

		return (now.compareTo(tsStart) >= 0 && now.compareTo(tsEnd) <= 0);
	}

	public static boolean betweenTime(Timestamp startTime, Timestamp endTime) {
		long nowTime = System.currentTimeMillis();
		return (nowTime >= startTime.getTime() && nowTime <= endTime.getTime());
	}
	
	public static boolean beforeDateTime (Timestamp oneTime, Timestamp twoTime) {
		if(oneTime==null || twoTime==null) return false ;
		return oneTime.getTime() > twoTime.getTime() ;
	}
	
	public static boolean beforeDateTime (String oneTime, String twoTime) {
		Timestamp one = str2Date(oneTime, DATETIME_PATTERN);
		Timestamp two = str2Date(twoTime, DATETIME_PATTERN);
		return beforeDateTime(one, two);
	}
	
	public static boolean beforeDateTime (Timestamp oneTime, String twoTime) {
		Timestamp two = str2Date(twoTime, DATETIME_PATTERN);
		return beforeDateTime(oneTime, two);
	}
	
	

	/**
	 * 当前时间是否在某个时间段内 ,掉落处理
	 * 
	 * @param startTime
	 *            HH:MM:SS
	 * @param endTime
	 *            HH:MM:SS
	 * @return
	 */
	public static boolean betweenTimeDrop(Timestamp startTime,
			Timestamp endTime, Timestamp nowTime) {

		return (nowTime.compareTo(startTime) >= 0 && nowTime.compareTo(endTime) <= 0);
	}

	/**
	 * Timestamp to Str, 只要时间部分HH:mm:ss
	 */
	public static String getTime(Date date) {
		return getDatetime(date, TIME_PATTERN);
	}

	/**
	 * 格式化日期，保留日期部分yyyy-MM-dd
	 */
	public static String getDate(Date date) {
		return getDatetime(date, DATE_PATTERN);
	}
		
	public static String date2Text(String pattern) {
		return getDatetime(new Date(), pattern);
	}
	
	public static String getDatetime(Date date, String pattern) {
		if (date == null) return null;
		if(pattern==null || pattern.equals("")) pattern = DATETIME_PATTERN ;
		
		try{
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			return sdf.format(date) ;
		} catch(Exception e) {
			return null ;
		}		
	}

	/**
	 * string to timstamp, with "yyyy-MM-dd HH:mm:ss.fffffffff"
	 * 
	 * @param asDate
	 * @return
	 */
	public static Timestamp str2Date(String asDate) {
		return str2Date(asDate, DATETIME_PATTERN);
	}

	/**
	 * string to timestamp, with given pattern
	 * 
	 * @param asDate
	 * @param asPattern
	 * @return
	 */
	public static Timestamp str2Date(String asDate, String asPattern) {
		java.sql.Timestamp lStamp = null;
		if (asDate == null)
			return null;

			try {
				SimpleDateFormat lFormat = new SimpleDateFormat(asPattern);
				lStamp = new java.sql.Timestamp(lFormat.parse(asDate).getTime());
			} catch (Exception e) {
				return null;
			}
	

		return lStamp;
	}

	public static java.util.Date text2Date(String text) {
		return text2Date(text, DATETIME_PATTERN);
	}

	public static java.util.Date datetime2Text(String text) {
		return text2Date(text, DATETIME_PATTERN);
	}

	public static java.util.Date text2Date(String text, String pattern) {
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		Date date = null;
		try {
			date = formatter.parse(text);
		} catch (Exception e) {
		}
		return date;
	}



	/**
	 * 计算两个日期之间的天数
	 * @param smallDate
	 * @param bigDate
	 * @return
	 */
	public static int daysOfTwo(Date smallDate, Date bigDate) {
		Calendar aCalendar = Calendar.getInstance();
		aCalendar.setTime(smallDate);
		int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
		aCalendar.setTime(bigDate);
		int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
		return Math.abs(day2 - day1);
	}
	
	/**
	 * 计算该日期与当前日期之间的天数
	 * @param smallDate
	 * @return
	 */
	public static int daysOfTwo(Date smallDate) {
		return daysOfTwo(smallDate, new Date());
	}
	
	/**
	 * 计算两个日期之间的天数
	 * @param smallDateStr
	 * @param bigDateStr
	 * @return
	 */
	public static int daysOfTwo (String smallDateStr, String bigDateStr) {
		Date smallDate = text2Date(smallDateStr, DATE_PATTERN) ;
		Date bigDate   = text2Date(bigDateStr, DATE_PATTERN) ;
		return daysOfTwo(smallDate, bigDate);
	}
	
	/**
	 * 计算该日期与当前日期之间的天数
	 * @param smallDateStr
	 * @return
	 */
	public static int daysOfTwo (String smallDateStr) {
		Date smallDate = text2Date(smallDateStr, DATE_PATTERN) ;
		return daysOfTwo(smallDate, new Date());
	}
	

	/**
	 * 获取星期几
	 * w的值 从周日开始：
	 *  0=星期日 , ......  6=星期六
	 * @return
	 */
	public static int getWeekDay () {
		Calendar cal = Calendar.getInstance(); 
		cal.setTime(new Date()); 
		int w = cal.get(Calendar.DAY_OF_WEEK)-1; 
		if (w < 0) w = 0;
		return w ;
	}
	
	/**
	 * 获取今日的最终截止时间
	 * @return
	 */
	public static long getTodayEndTime () {
		String today = date2Text(DATE_PATTERN) ;
		Timestamp todayEnd = str2Date(today + " 23:59:59") ;
		return (todayEnd == null) ?  0L : todayEnd.getTime() ;
	}
	
	/**
	 * 本日剩余的毫秒数
	 * @return
	 */
	public static long getTodayLeftTime () {
		int nowHour = getHours();
		return (24 - nowHour) * 3600000 ; 
	}
	
	
	/**
	 * 当前时间格式化
	 * @param formatter
	 * @return
	 */
	public static String formatterDate(String formatter){
		SimpleDateFormat format = new SimpleDateFormat(formatter);
		Date nowDate = new Date();
		return format.format(nowDate);
	}
	
	
	/**
	 * 时间格式化
	 * @param formatter
	 * @param mills
	 * @return
	 */
	public static String formatterDate(String formatter,long mills){
		SimpleDateFormat format = new SimpleDateFormat(formatter);
		Date nowDate = new Date(mills);
		return format.format(nowDate);
	}
	
	 
	public static boolean compareToSysTime(long time,int i){
		boolean re = false;
		if((new Date().getTime()/1000-time)<i){
			re = true;
		}
		return re;
	}
	
	public static void main(String[] args) {
	
		SimpleDateFormat formatter = new SimpleDateFormat(DATETIME_PATTERN);
		System.err.println(formatterDate(DATETIME_PATTERN,(System.currentTimeMillis()+24*60*60*1000)));
	}
	
}
